package com.majiang.majiang.service;

import com.majiang.majiang.domain.MaJiang;
import com.majiang.majiang.util.MaJiangFactory;
import com.majiang.majiang.util.PrintUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.util.*;

/**
 * 洗牌
 */
@Getter
@Setter
@ToString
public class ShuffleMaJiang {
    /**
     * 牌局中所有的牌：使用List放所有的牌
     */
    private List<MaJiang> maJiangs = new ArrayList<>();
    /**
     * 用来指示“牌局中所有的牌”的当前下标
     */
    private int maJiangsIndex = 0;
    /**
     * 河：用来存放玩家打出的牌
     */
    private List<MaJiang> river = new ArrayList<>();
    /**
     * 用来指示“河”的当前下标
     */
    private int riverIndex = 0;

    private Integer[] c = {11, 12, 13, 14, 15, 16, 17, 18, 19, //1-9万
                            21, 22, 23, 24, 25, 26, 27, 28, 29, //1-9饼
                            31, 32, 33, 34, 35, 36, 37, 38, 39, //1-9条
                            40, 50, 60, 70, 80, 90, 100}; //东南西北中发白

    private Map<Integer, MaJiang> map = new HashMap<>();

    public ShuffleMaJiang() throws InterruptedException {
        //创建一副麻将
        createMaJiangs();
        //输出此时的所有的牌
        System.out.println("【初始化所有的牌：】");
        printMaJiangs(0);
        //把初始牌打乱
        chaosMaJiangs();
        //输出此时的所有的牌
        System.out.println("【洗牌后所有的牌：】");
        printMaJiangs(0);
        System.out.println("【按照东南西北四个方向输出的牌(牌局里的牌)：】");
        printMaJiangs(1);
        //下标恢复
        riverIndex=0;
        maJiangsIndex=135;
    }

    /**
     * 创建一副麻将
     * @throws InterruptedException 异常
     */
    private void createMaJiangs() throws InterruptedException {
        //创建麻将的工厂
        MaJiangFactory maJiangFactory = new MaJiangFactory();
        maJiangs = maJiangFactory.createMaJiang(map);
        maJiangsIndex += maJiangs.size();
        System.out.println();
        //睡一会，显得更加逼真
        Thread.sleep(100);
    }

    /**
     * 输出一副牌
     * @param direction 0表示输出为一行，1表示按照四个方位进行输出
     * @throws InterruptedException 异常
     */
    public void printMaJiangs(int direction) throws InterruptedException {
        for (int i = 0; i < maJiangs.size(); i++) {
            //以下是按照方位输出
            if (direction == 1) {
                if (i == 0) {
                    System.out.print("【桌子东方（玩家）】");
                }else if(i == 34){
                    System.out.print("\n【桌子南方（电脑）】");
                }else if(i == 68){
                    System.out.print("\n【桌子西方（电脑）】");
                }else if(i == 102){
                    System.out.print("\n【桌子北方（电脑）】");
                }
            }
            MaJiang maJiangTemp = maJiangs.get(i);
            PrintUtil.printMaJiang(maJiangTemp);
        }
        System.out.println();
        //睡一会，显得更加逼真
        Thread.sleep(100);
    }

    /**
     * 把初始牌打乱
     */
    private void chaosMaJiangs(){
        //洗牌
        Collections.shuffle(maJiangs);
    }

    /**
     * 由于第一次起牌很有可能是在整副牌的中间位置开始起牌的，然后再向后起牌。此时需要把起始位置前的牌，重新放到maJiangs中的最后，来保证整副牌的完整性
     * @throws InterruptedException 异常
     */
    public void moveMaJiangs() throws InterruptedException{
        //把开始位置前的牌复制到list的末尾
        for (int i = 0; i < maJiangsIndex; i++) {
            maJiangs.add(maJiangs.size(), maJiangs.get(i));
        }
        //复制后，把开始位置前的牌删除
        for (int i = 0; i < maJiangsIndex; i++) {
            maJiangs.remove(i);
        }
        //输出移动位置后的整副牌
        System.out.println("【移动位置后的整副牌：】");
        printMaJiangs(0);
        //移动过后，起始位置变为了第一张牌，需要把下标复位
        maJiangsIndex = 0;
    }

    /**
     * 输出河里的牌
     * @throws InterruptedException 异常
     */
    public void printMaJiangsRiver() throws InterruptedException {
        for (MaJiang maJiangTemp: river) {
            PrintUtil.printMaJiang(maJiangTemp);
        }
        System.out.println();
        //睡一会，显得更加逼真
        Thread.sleep(100);
    }

    public void isEnd(){
        if (this.getMaJiangs().size()==0) {
            System.out.println("【留局】");
            System.out.println("【游戏结束，再见！】");
            System.exit(0);
        }
    }

    public void huEnd(){
        System.out.println("【游戏结束，再见！】");
        System.exit(0);
    }

    public Integer[] getType(){
        return this.c;
    }

    public MaJiang getPaiName(Integer code){
        return this.map.get(code);
    }
}
